/*
Xern Entity Relocation Network
Copyright (C) 2011 Ronie Salgado <roniesalg@gmail.com>

This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/

#ifndef MAP_PROCESSOR_HPP
#define MAP_PROCESSOR_HPP

#include "MapData.hpp"

namespace MapXern
{
	// Map traversing helper functions.

	// Face processor.
	template <typename FUNCTOR>
	struct _FaceProcessor
	{
		_FaceProcessor(FUNCTOR functor)
			: functor(functor) {}

		void operator()(boost::shared_ptr<Object> object)
		{
			boost::shared_ptr<Brush> brush = object->brush;
			if(brush)
			{
				for(size_t i = 0; i < brush->faces.size(); i++)
					functor(brush->faces[i]);
			}
		}

		FUNCTOR functor;
	};

	template <typename FUNCTOR>
	inline _FaceProcessor<FUNCTOR> FaceProcessor(const FUNCTOR &functor)
	{
		return _FaceProcessor<FUNCTOR> (functor);
	}

	template <typename FUNCTOR>
	inline _FaceProcessor<FUNCTOR*> FaceProcessor(FUNCTOR *functor)
	{
		return _FaceProcessor<FUNCTOR*> (functor);
	}

	// Brush processor.
	template <typename FUNCTOR>
	struct _BrushProcessor
	{
		_BrushProcessor(FUNCTOR functor)
			: functor(functor) {}

		void operator()(boost::shared_ptr<Object> object)
		{
			if(object->brush)
				functor(object->brush);
		}

		FUNCTOR functor;
	};

	template <typename FUNCTOR>
	inline _BrushProcessor<FUNCTOR> BrushProcessor(const FUNCTOR &functor)
	{
		return _BrushProcessor<FUNCTOR> (functor);
	}

	template <typename FUNCTOR>
	inline _BrushProcessor<FUNCTOR*> BrushProcessor(FUNCTOR *functor)
	{
		return _BrushProcessor<FUNCTOR*> (functor);
	}

	// Entity processor.
	template <typename FUNCTOR>
	struct _EntityProcessor
	{
		_EntityProcessor(FUNCTOR functor)
			: functor(functor) {}

		void operator()(boost::shared_ptr<Object> object)
		{
			if(object->entity)
				functor(object->entity);
		}

		FUNCTOR functor;
	};

	template <typename FUNCTOR>
	inline _EntityProcessor<FUNCTOR> EntityProcessor(const FUNCTOR &functor)
	{
		return _EntityProcessor<FUNCTOR> (functor);
	}


	template <typename FUNCTOR>
	inline _EntityProcessor<FUNCTOR*> EntityProcessor(FUNCTOR *functor)
	{
		return _EntityProcessor<FUNCTOR*> (functor);
	}

	// Processing functions.
	void NormalizeBrush(boost::shared_ptr<Brush> brush);
	void SortFaceVertices(BrushFace &face);
	void GenerateTexCoords(BrushFace &face);
	void GenerateTBN(BrushFace &face);
	void TriangulateFace(BrushFace &face);
};

#endif //MAP_PROCESSOR_HPP
